// utils/http.js
// console.log(process,'process');
import md5 from 'js-md5';
// 基础配置
const config = {
  baseURL: 'https://pre.goldfull.cc/api',
  timeout: 10000, // 请求超时时间
  header: {
    'Content-Type': 'application/json;charset=UTF-8' // 默认  
  }
}
let optionsObj = {}
// 请求队列（用于取消请求）
const requestQueue = new Map()

/**
 * 封装uni.request
 * @param {Object} options 请求配置
 * @returns {Promise} 返回Promise对象
 */
function request(options) {
 
  // console.log(1, options, 'options');
  
  // 合并配置
  options = Object.assign({}, config, options)
  // 处理请求URL
  if (!options.url.startsWith('http') && !options.url.startsWith('https')) {
    
    options.url = config.baseURL + options.url
  }
  
  const timestamp = Date.now()
  // 生成8-10位随机字符串
  const generateNonce = () => {
    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
    const length = Math.floor(Math.random() * 3) + 8 // 8-10位随机长度
    let result = ''
    for (let i = 0; i < length; i++) {
      result += chars.charAt(Math.floor(Math.random() * chars.length))
    }
    return result
  }
  const nonce = generateNonce()
  options.header.signature = md5("timestamp="+timestamp+"&nonce="+nonce+"&01e553a3697a0479bac95466cea61487e1dba680").toString();
  options.header.timestamp = timestamp
  options.header.nonce = nonce
  
  // 添加token到header
  const token = uni.getStorageSync('token')
  if (token) {
    options.header = options.header || {}
    options.header.appletToken = `${token}`
    // if(options.url.includes('upload')){
    //   config.header['Content-Type'] = 'multipart/form-data'
    // }
    
  }
  const openId = uni.getStorageSync('openId')
  if (openId) {
    options.header = options.header || {}
    options.header.openId = `${openId}`
  }
  
  // 生成请求唯一标识（用于取消请求）
  const requestKey = `${options.method}_${options.url}_${JSON.stringify(options.data)}`
  optionsObj = options
  return new Promise((resolve, reject) => {
    // 添加到请求队列
    requestQueue.set(requestKey, { resolve, reject })
    
    // 发起请求
    const requestTask = uni.request({
      ...options,
      success: (res) => {
        // 从队列中移除
        requestQueue.delete(requestKey)
        
        // 响应拦截处理
        handleResponse(res, resolve, reject)
      },
      fail: (err) => {
        // 从队列中移除
        requestQueue.delete(requestKey)
        
        // 错误处理
        handleError(err, reject)
      },
      complete: () => {
        // 可以在这里处理loading状态等
      }
    })
    
    // 如果需要取消请求，可以保存requestTask
    requestQueue.get(requestKey).task = requestTask
  })
}

/**
 * 处理响应
 */
function handleResponse(res, resolve, reject) {
  // console.log(res, '处理响应');
  
  const { statusCode, data, errMsg } = res
  
  // 状态码判断
  if (statusCode == 200) {
    
    // 业务状态码处理 （根据后端接口规范调整）
    if (data.code == 200) {
      
      resolve(data)
    } else {
      // 业务错误处理
      handleBusinessError(data, reject)
    }
  } else {
    // HTTP状态码错误处理
    handleHttpError(statusCode, reject)
  }
}

/**
 * 处理业务错误
 */
function handleBusinessError(data, reject) {
  console.log('处理业务错误', data);
  
  const { code, msg, data:data2 } = data
  
  // 未登录或token过期
  if (code === 401 || code === 403 || code === 402) {
    uni.showToast({
      title: msg || '登录已过期，请重新登录',
      icon: 'none'
    })
    // 清除token
    uni.removeStorageSync('token');
	uni.removeStorageSync('customerInfo');
    return
  }
  
  // 其他业务错误
  uni.showToast({
    title: msg || '请求失败',
    icon: 'none',
    duration: 3000 // 显示时间为 5 秒

  })
  
  reject(data)
}

/**
 * 处理HTTP错误
 */
function handleHttpError(statusCode, reject) {
  let errMessage = '请求失败'
  
  switch (statusCode) {
    case 400:
      errMessage = '请求错误'
      break
    case 401:
      errMessage = '未授权，请登录'
      break
    case 403:
      errMessage = '拒绝访问'
      break
    case 404:
      errMessage = '请求地址不存在'
      break
    case 500:
      errMessage = '服务器内部错误'
      break
    case 502:
      errMessage = '网关错误'
      break
    case 503:
      errMessage = '服务不可用'
      break
    case 504:
      errMessage = '网关超时'
      break
  }
  
  uni.showToast({
    title: errMessage,
    icon: 'none'
  })
  
  reject({ code: statusCode, message: errMessage })
}

/**
 * 处理网络错误
 */
function handleError(err, reject) {
  uni.showToast({
    title: '网络错误，请检查网络连接',
    icon: 'none'
  })
  
  reject({ code: -1, message: '网络错误' })
}

/**
 * 取消请求
 * @param {String} requestKey 请求唯一标识
 */
function cancelRequest(requestKey) {
  if (requestQueue.has(requestKey)) {
    const { task, reject } = requestQueue.get(requestKey)
    task.abort()
    reject({ code: -2, message: '请求已取消' })
    requestQueue.delete(requestKey)
  }
}

/**
 * 取消所有请求
 */
function cancelAllRequests() {
  requestQueue.forEach(({ task, reject }) => {
    task.abort()
    reject({ code: -2, message: '请求已取消' })
  })
  requestQueue.clear()
}
/**
 * 文件上传
 * @param {String} url 上传地址
 * @param {String} filePath 文件路径
 * @param {String} name 文件对应的key
 * @param {Object} formData 其他表单数据
 * @param {Object} options 其他配置
 */
function uploadFile(url, filePath, name = 'file', formData = {}, options = {}) {
  // 处理URL
  if (!url.startsWith('http') && !url.startsWith('https')) {
    url = config.baseURL + url
  }
  
  // 添加token
  const header = options.header || {}
  const token = uni.getStorageSync('token')
  if (token) {
    header.Authorization = `Bearer ${token}`,
    header['Content-Type'] = 'multipart/form-data'
  }
  
  return new Promise((resolve, reject) => {
    const uploadTask = uni.uploadFile({
      url,
      filePath,
      name,
      formData,
      header,
      success: (res) => {
        
        if (res.statusCode === 200) {
          try {
            const data = JSON.parse(res.data)
            resolve(data)
          } catch (e) {
            resolve(res.data)
          }
        } else {
          handleHttpError(res.statusCode, reject)
        }
      },
      fail: (err) => {
        handleError(err, reject)
      }
    })
    
    // 可以返回uploadTask以便监听进度
    options.onProgressUpdate && uploadTask.onProgressUpdate(options.onProgressUpdate)
  })
}


// 导出常用方法
export default {
  request,
  get(url, data, options = {}) {
    return request({
      url,
      data,
      method: 'GET',
      ...options
    })
  },
  post(url, data, options = {}) {
    return request({
      url,
      data,
      method: 'POST',
      ...options
    })
  },
  put(url, data, options = {}) {
    return request({
      url,
      data,
      method: 'PUT',
      ...options
    })
  },
  delete(url, data, options = {}) {
    return request({
      url,
      data,
      method: 'DELETE',
      ...options
    })
  },
  cancelRequest,
  cancelAllRequests,
  uploadFile
}